package com.vo;

import java.io.Serializable;
import java.util.*;

/**
 * Classe Event utilizada como Variable Object.
 * @author Jean Vasconcelos, Carla Sukeyosi, Matheus Emanuel, Heitor Carvalho
 */
public class Event implements Serializable
{
    private String name;
    private String description;
    private String type;
    private Interval interval;
    private List<Contact> contacts;
    private List<Note> notes;

    /**
     * Cria um Evento a partir do nome, tipo, intervalo(Interval).
     * @param name Nome do Evento.
     * @param type Tipo do Evento.
     * @param interval Intervalo(Interval) do Evento.
     */
    public Event(String name, String type, Interval interval)
    {
        this.name     = name;
        this.type     = type;
        this.interval = interval;
        this.contacts = new ArrayList<Contact>();
        this.notes = new ArrayList<Note>();
    }

    /**
     * Recupera a descricao do Evento.
     * @return Descricao do evento.
     */
    public String getDescription()
    {
        return description;
    }
    
    /**
     * Altera a descricao do Evento.
     * @return Descricao do Evento.
     */
    public void setDescription(String description)
    {
        this.description = description;
    }

    /**
     * Recupera o intervalo(Interval) do Evento.
     * @return Intervalo(Interval) do Evento.
     */
    public Interval getInterval()
    {
        return interval;
    }
    
    /**
     * Modifica o intervalo(Interval) do Evento.
     * @param interval Novo intervalo(Interval). 
     */
    public void setInterval(Interval interval)
    {
        this.interval = interval;
    }

    /**
     * Recupera o nome do Evento.
     * @return Nome do Evento.
     */
    public String getName()
    {
        return name;
    }
    
    /**
     * Altera o nome do Evento.
     * @param name Novo nome do Evento.
     */
     public void setName(String name)
    {
        this.name = name;
    }

    /**
     * Recupera o tipo do Evento.
     * @return Tipo do evento.
     */
    public String getType()
    {
        return type;
    }
    
    /**
     * Altera o tipo do Evento.
     * @param type Novo tipo.
     */
    public void setType(String type)
    {
        this.type = type;
    }        

    /**
     * Recupera a lista<contatos(Contact)> do Evento.
     * @return Lista<contatos(Contact)>.
     */
    public List getContacts ()
    {
        return contacts;
    }
    
    /**
     * Recupera a lista<anotacoes(Note)> do Evento.
     * @return Lista<anotacoes(Note)>.
     */
    public List getNotes ()
    {
        return notes;
    }
    
    /**
     * Adiciona Contato(Contact) na lista<contatos> do Evento. Caso o Contanto já
     * esteja na lista, não será adicionado novamente.
     * @param contact Contato a ser adicionado.
     * @return true se o elemento for adicionado a lista.
     */
    public boolean addContact (Contact contact)
    {
        if (!contacts.contains(contact))
        {
            return contacts.add(contact);
        } return false;
    }
    
    /**
     * Remove Contato(Contact) da lista<contatos> do Evento.
     * @param contact Contato a ser removido.
     * @return true se o elemento for removido.
     */
    public boolean removeContact (Contact contact)
    {
        return contacts.remove(contact);
    }    
    
    /**
     * Adiciona Anotação(Note) na lista<anotações> do Evento. Caso a Anotação já
     * esteja na lista, não será adicionada novamente.
     * @param note Anotação(Note) a ser adicionada.
     * @return true se o elemento for adicionado a lista.
     */
    public boolean addNote (Note note)
    {
        if (!notes.contains(note))
            return notes.add(note);
        return false;
    }
    
    /**
     * Remove Anotação(Note) da lista<anotações> do Evento.
     * @param note Anotação(Note) a ser removida.
     * @return true se o elemento for removido.
     */
    public boolean removeNote (Note note)
    {
        return notes.remove(note);
    }  

    /**
     * Gera o hascode do Evento a partir do nome, descrição e tipo.
     * @return Hascode do Evento.
     */
    @Override
    public int hashCode()
    {
        int hash = 7;
        hash = 23 * hash + (this.name != null ? this.name.toLowerCase().hashCode() : 0);
        hash = 23 * hash + (this.description != null ? this.description.toLowerCase().hashCode() : 0);
        hash = 23 * hash + (this.type != null ? this.type.toLowerCase().hashCode() : 0);
        return hash;
    }
    
    /**
     * Verifica se dois Eventos são iguais, no caso de possuirem o mesmo nome, descrição
     * e tipo.
     * @param obj Evento a ser comparado.
     * @return true caso os Eventos sejam iguais.
     */
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Event other = (Event) obj;
        if (other.hashCode() != this.hashCode())
            return false;
        return true;
    }
    
    /**
     * Representação das informações do Evento num string.
     * @return String com as informações do Evento.
     */
    @Override
    public String toString() 
    {
        String sContacts = "[";
        int len = contacts.size();
        for (int i = 0; i < len; i++)
        {
            if (len > 1)
                if (i < (len-1))
                    sContacts += contacts.get(i).getName() + ", ";
                else
                    sContacts += contacts.get(i).getName();
            else
                sContacts += contacts.get(i).getName();
        }
        return "Evento: " + name + "\nDescrição: " + description + "\nTipo: " + type + "\nData/Hora: " 
                + interval + "\nContatos: " + sContacts + "]";
    }
}
